
/**
 * @file voltage_control.c
 * @brief 
 * @author rendong (rendong@littt.com) 
 * @version 1.0
 * @date 2020-11-16
 * 
 * @copyright Copyright (c) 2020  成都科鸿凌泰自动识别
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2020-11-16 <td>1.0     <td>rendong     <td>内容
 * </table>
 */

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "kvconf.h"
#include "./write_log/write_log.h"


#define APP_VERSION 0x01 // 版本号


#define GPIO_Base_addr 0xFED0E000
#define GPIO_Page_size 4096

#define GPIO31_CFG_ADDR 0x330 //供电检测引脚
#define GPIO31_PORT_ADDR (GPIO31_CFG_ADDR + 8)

#define GPIO_CFG_Value 0x2003CD00
#define GPIO_PORT_CFG_Value 0x00000003

#define Existence_of_electricity 0x01
#define No_electricity 0x00

void read_return(unsigned char *str, char *ret_buf)
{
    FILE *stream;
    char buf[1024];
    memset(buf, '\0', sizeof(buf));

    stream = popen(str, "r");
    fread(buf, sizeof(char), sizeof(buf), stream);
    pclose(stream);
    // printf("%s\n", buf);
    // return buf;
    memcpy(ret_buf, buf, sizeof(buf));
    // printf("%s\n",strrstr(buf,"="));
}

#if 1

int main(int argc, char *argv[])
{
    uint8_t Value, fd;
    char *mem;
    uint64_t TMP = 0, i = 0, fileRecord_flag;
    uint8_t copy_action[100];
    uint8_t Delay_time = 5, poweron_flag = 1, poweroff_flag = 1;
    uint8_t cmd[100] = {0};
    uint8_t fileRecord_buffer[128] = {0};


    if (argc == 1)
    {
        Delay_time = 5;
    }
    else if (argc == 2)
    {
        Delay_time = atoi(argv[1]);
        //printf("Delay_time:%d\n",Delay_time);
    }
    //open /dev/mem with read and write mode
    if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
    {
        perror("open error");
        return -1;
    }
    //map physical memory 0-10 bytes
    mem = mmap(0, GPIO_Page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_Base_addr);
    if (mem == MAP_FAILED)
    {
        perror("mmap error:");
        return 1;
    }

    TMP = GPIO_CFG_Value;
    memcpy((mem + GPIO31_CFG_ADDR), &TMP, 4);
    TMP = GPIO_PORT_CFG_Value;
    memcpy((mem + GPIO31_PORT_ADDR), &TMP, 4);

    write_log_file(LOG_INFO, "voltage_control version: [0x%02X]", APP_VERSION);

    while (1)
    {
        sleep(1);

        Value = (*((int *)(mem + GPIO31_PORT_ADDR)) & 0x01);
        // printf("%d--%d\n",i,Value);
        if (Value == No_electricity)
        {
            ++i;
            if(poweroff_flag)
            {
                // memset(fileRecord_buffer, '\0', sizeof(fileRecord_buffer));
                // sprintf(fileRecord_buffer, "echo \"$(date)---第%d次关机\" >> /tmp/voltage_control.log", i);
                // system(fileRecord_buffer);
                // printf_log_info("voltage_control app start, app version: [0x%02X]\n", APP_VERSION);
                write_log_file(LOG_INFO, "外部电源断开: [0x%02X]", APP_VERSION);
                poweroff_flag = 0;
            }
            poweron_flag = 1;
        }
        else
        {
            i = 0;
            poweroff_flag = 1;
            if(poweron_flag)
            {
                write_log_file(LOG_INFO, "系统上电: [0x%02X]", APP_VERSION);
                poweron_flag = 0;
            }
        }


        if (Value == No_electricity && i >= Delay_time)
        {
            i = 0;

            memset(cmd, '\0', sizeof(cmd));
            GetProfileString("/root/voltage_control/cls.conf", "command_before_shutdown", "sync_cmd", cmd);
            if (*cmd != NULL)
                system(cmd);

            memset(cmd, '\0', sizeof(cmd));
            GetProfileString("/root/voltage_control/cls.conf", "command_before_shutdown", "other_cmd", cmd);
            if (*cmd != NULL)
                system(cmd);

            memset(cmd, '\0', sizeof(cmd));
            GetProfileString("/root/voltage_control/cls.conf", "command_before_shutdown", "poweroff_cmd", cmd);
            if (*cmd != NULL)
                system(cmd);

            write_log_file(LOG_INFO, "系统关机: [0x%02X]", APP_VERSION);
            munmap(mem, GPIO_Page_size);
            close(fd);
            return 0;
        }
    }

    munmap(mem, GPIO_Page_size); //destroy map memory
    close(fd);                   //close file

    return 0;
}

#else

int main(int argc, char *argv[])
{
    // frpint(stdout,"Length:""%d\n",strlen(shellcode));
    char cmd[100] = {0};
    GetProfileString("./cls.conf", "linux", "cmd", cmd);
    printf("%s\n", cmd);
    // system(ip);
    if (*cmd == NULL)
    {
        printf("111\n");
    }
    return 0;
}

#endif

// select poll会从用户态拷贝到内核态，增加开销
